package com.example.lib_rongrui;

import android.util.Base64;
import com.rfid.trans.ReadTag;
import com.rfid.trans.ReaderHelp;
import com.rfid.trans.ReaderParameter;
import com.rfid.trans.TagCallback;
import com.sum.common.bean.ReadMode;
import com.sum.common.bean.ReaderExt;
import com.sum.common.bean.Stats;
import com.sum.common.bean.TagInfo;
import com.sum.common.bean.WriteParams;
import com.sum.common.inter.IUHFManager;
import com.sum.common.inter.OnInventoryListener;
import com.sum.common.utils.LogU;
import com.sum.common.utils.MapUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class RongruiUHFManager implements IUHFManager {
    private volatile boolean isRunning;
    private volatile boolean isConnect;
    private final ReaderHelp mReader;
    private static volatile RongruiUHFManager mInstance;
    private OnInventoryListener tagListener;
    private volatile boolean isRealTime = true;

    private int maxSerialNumber;
    private int totalCount;
    private List<TagInfo> tagList; //获取标签数据
    private int tagCountPerSecond;

    private final TagCallback tagCallback = new TagCallback() {
        @Override
        public void tagCallback(ReadTag tag) {
            LogU.i("tagCallback epc:" + tag.epcId +
                    " ,mem:" + tag.memId +
                    " ,rssi:" + tag.rssi);
            if(isRunning || isRealTime){
                isRealTime = false;
                processTagInfo(tag);
                if (tagListener != null) {
                    tagListener.onInventoryListener(tagList, new Stats(tagCountPerSecond,maxSerialNumber,totalCount));
                }
            }
        }

        @Override
        public void StopReadCallBack() {
            // Stop read callback implementation
        }
    };
    private long startTime = System.currentTimeMillis();


    private void processTagInfo(ReadTag tag) {
        String epcId = tag.epcId;
        int rssi = tag.rssi;
        String memId = tag.memId;

        synchronized (tagList) {
            // 查找已存在的标签
            int findIndex = -1;
            for(int i =0;i<tagList.size();i++){
                if (tagList.get(i).getEpc().equals(epcId)) {
                    findIndex = i;
                    break;
                }
            }

            if (findIndex != -1) {
                TagInfo tagInfo= tagList.get(findIndex);
                // 更新已存在的标签
                tagInfo.setCount(tagInfo.getCount() + 1);
                tagInfo.setRssi(rssi);
                tagList.remove(findIndex);
                tagList.add(tagInfo);
            } else {
                // 添加新标签
                TagInfo newTag = new TagInfo();
                newTag.setEpc(epcId);
                newTag.setCount(1);
                newTag.setRssi(rssi);
                newTag.setTid(memId);
                newTag.setSerialNumber(tagList.size()+1);
                tagList.add(newTag);
            }
            //最大排列序号(标签个数)
            maxSerialNumber = tagList.size();
            //读取到标签总数
            totalCount = 0;

            for (int i = 1; i < tagList.size(); i++) {
                TagInfo item = tagList.get(i);
                totalCount += item.getCount();
            }
            //获取每秒所读张数
            int seconds = (int)((System.currentTimeMillis() - startTime) / 1000);
            if(seconds>1){
                tagCountPerSecond = totalCount/seconds;
            }
            //添加代码排序
            Collections.sort(tagList, (t1, t2) ->
                    Integer.compare(t1.getSerialNumber(), t2.getSerialNumber()));
        }
    }

    private RongruiUHFManager() {
        this.tagList = Collections.synchronizedList(new ArrayList<>());
        mReader = new ReaderHelp();
        mReader.SetCallBack(tagCallback);
    }

    @Override
    public IUHFManager getInstance() {
        if (mInstance == null) {
            synchronized (RongruiUHFManager.class) {
                if (mInstance == null) {
                    mInstance = new RongruiUHFManager();
                }
            }
        }
        return mInstance;
    }

    @Override
    public boolean connect(String port, int baudRate) {
        LogU.d("RongRuiUHFManager connect isConnect:"+isConnect);
        if (isConnect) {
            return true;
        }
        try {
            LogU.d("RongRuiUHFManager connect port:"+port+" ,baudRate:"+baudRate);
            int result = mReader.Connect(port, baudRate, 1);
            LogU.d("RongRuiUHFManager connect result:"+result);
            if (result == 0) {
                isConnect = true;
                initRfid();
            }else {
                close();
            }
        } catch (Exception e) {
            LogU.d("RongRuiUHFManager connect err:"+e.getMessage());
        } catch (Error e){
            LogU.d("RongRuiUHFManager connect Error:"+e.getMessage());
        }
        return isConnect;
    }

    private void initRfid() {
        int readerType = mReader.GetReaderType();
        ReaderParameter param = mReader.GetInventoryPatameter();

        // 根据读写器类型设置Session
        switch (readerType) {
            case 0x21:
            case 0x28:
            case 0x23:
            case 0x37:
            case 0x36: // R2000
                param.Session =  1;
                break;
            case 0x70:
            case 0x71:
            case 0x31: // Ex10
                param.Session = 254;
                break;
            case 0x61:
            case 0x63:
            case 0x65:
            case 0x66: // C6
                param.Session =  1;
                break;
            default:
                param.Session = 0;
                break;
        }
        mReader.SetInventoryPatameter(param);
        mReader.SetRfPower((byte) 32);
    }

    @Override
    public boolean isConnected() {
        return isConnect;
    }

    @Override
    public String getHardware() {
        byte[] version = new byte[2];
        byte[] power = new byte[1];
        byte[] band = new byte[1];
        byte[] maxFre = new byte[1];
        byte[] minFre = new byte[1];
        try {
            int result = mReader.GetReaderInformation(version, power, band, maxFre, minFre);
            Map<String, Object> info = new HashMap<>();
            info.put("code", result);
            info.put("version", Base64.encodeToString(version, Base64.DEFAULT));
            info.put("power", power[0]);
            info.put("band", band[0]);
            info.put("maxFre", maxFre[0]);
            info.put("minFre", minFre[0]);
            return MapUtils.mapToString(info);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public ReaderExt.READER_ERR getLastDetailError(ReaderExt.ErrInfo info) {
        return ReaderExt.READER_ERR.MT_OK_ERR;
    }

    @Override
    public void clearTagList() {
        tagCountPerSecond = 0;
        if(!tagList.isEmpty()){
            tagList.clear();
        }
        maxSerialNumber=0;
        totalCount=0;
    }

    @Override
    public void setOnInventoryListener(OnInventoryListener listener) {
        this.tagListener = listener;
    }

    @Override
    public ReaderExt.READER_ERR asyncStartReading(ReadMode readMode) {
        isRunning = true;
        startTime = System.currentTimeMillis();
        try {
            int code = mReader.StartRead();
            return code == 0 ? ReaderExt.READER_ERR.MT_OK_ERR : ReaderExt.READER_ERR.MT_OTHER_ERR;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ReaderExt.READER_ERR.MT_OTHER_ERR;
    }

    @Override
    public ReaderExt.READER_ERR asyncStopReading() {
        isRunning = false;
        try {
            mReader.StopRead();
            return ReaderExt.READER_ERR.MT_OK_ERR;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ReaderExt.READER_ERR.MT_OTHER_ERR;
    }

    @Override
    public boolean setInventoryFilter(byte[] fdata, int fbank, int fstartaddr, boolean matching) {
        try {
            ReaderParameter param = mReader.GetInventoryPatameter();
            param.MaskMem = (byte) fbank;
            param.MaskLen = (byte) (fdata.length * 8); // 转换为位长度
            System.arraycopy(fdata, 0, param.MaskData, 0, fdata.length);

            // 将起始地址转换为两个字节
            param.MaskAdr[0] = (byte) (fstartaddr >> 8);
            param.MaskAdr[1] = (byte) fstartaddr;

            mReader.SetInventoryPatameter(param);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public boolean setCancleInventoryFilter() {
        try {
            ReaderParameter param = mReader.GetInventoryPatameter();
            param.MaskLen  =(byte) 0; // 设置掩码长度为0表示不启用掩码
            mReader.SetInventoryPatameter(param);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public List<TagInfo> tagInventoryRealTime() {
        isRunning = false;
        isRealTime = true;
        return null;
    }

    @Override
    public boolean stopTagInventory() {
        isRunning = false;
        isRealTime = false;
        return false;
    }

    @Override
    public List<TagInfo> tagInventoryByTimer(short readtime) {
        try {
            // 使用单次询查命令，设置扫描时间
            mReader.InventoryOnce(
                    (byte) 0,  // session S0
                    (byte) 4,  // Q值默认4
                    (byte) 0,  // TID起始地址
                    (byte) 0,  // TID长度
                    (byte) 0x80, // 天线
                    (byte) 0,  // Target A
                    (byte) readtime // 扫描时间
            );
            return null; // 标签数据会通过回调返回
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public ReaderExt.READER_ERR getTagData(int mbank, int startaddr, int len,
                                           byte[] rdata, byte[] password, short timeout) {
        try {
            byte[] errorcode = new byte[1];
            int result = mReader.ReadData_G2(
                    (byte) 0, // 广播方式
                    new byte[0], // EPC为空
                    (byte) mbank,
                    startaddr,
                    (byte) len,
                    password,
                    rdata,
                    errorcode
            );
            return result == 0 ? ReaderExt.READER_ERR.MT_OK_ERR : ReaderExt.READER_ERR.MT_OTHER_ERR;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ReaderExt.READER_ERR.MT_OTHER_ERR;
    }

    @Override
    public byte[] getTagDataByFilter(int mbank, int startaddr, int len,
                                     byte[] password, short timeout, byte[] fdata,
                                     int fbank, int fstartaddr, boolean matching) {
        try {
            byte[] rdata = new byte[len * 2]; // 每个字占2个字节
            byte[] errorcode = new byte[1];

            // 设置过滤器
            setInventoryFilter(fdata, fbank, fstartaddr, matching);

            int result = mReader.ReadData_G2(
                    (byte) 255, // 使用掩码方式
                    new byte[0], // EPC为空
                    (byte) mbank,
                    startaddr,
                    (byte) len,
                    password,
                    rdata,
                    errorcode
            );

            return result == 0 ? rdata : null;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            setCancleInventoryFilter();
        }
        return null;
    }

    @Override
    public ReaderExt.READER_ERR writeTagData(WriteParams writeParams, int mbank, int startaddress, String oldData,
                                             byte[] data, int datalen, byte[] accesspasswd, short timeout) {
        try {
            byte[] errorcode = new byte[1];
            int result = mReader.WriteData_G2(
                    (byte) (datalen / 2), // 字数
                    (byte) 0, // 广播方式
                    new byte[0], // EPC为空
                    (byte) mbank,
                    startaddress,
                    data,
                    accesspasswd,
                    errorcode
            );
            return result == 0 ? ReaderExt.READER_ERR.MT_OK_ERR : ReaderExt.READER_ERR.MT_OTHER_ERR;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ReaderExt.READER_ERR.MT_OTHER_ERR;
    }

    @Override
    public ReaderExt.READER_ERR writeTagDataByFilter(char mbank, int startaddress,
                                                     byte[] data, int datalen, byte[] accesspasswd, short timeout,
                                                     byte[] fdata, int fbank, int fstartaddr, boolean matching) {
        try {
            // 设置过滤器
            setInventoryFilter(fdata, fbank, fstartaddr, matching);

            byte[] errorcode = new byte[1];
            int result = mReader.WriteData_G2(
                    (byte) (datalen / 2), // 字数
                    (byte) 255, // 使用掩码方式
                    new byte[0], // EPC为空
                    (byte) mbank,
                    startaddress,
                    data,
                    accesspasswd,
                    errorcode
            );
            return result == 0 ? ReaderExt.READER_ERR.MT_OK_ERR : ReaderExt.READER_ERR.MT_OTHER_ERR;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            setCancleInventoryFilter();
        }
        return ReaderExt.READER_ERR.MT_OTHER_ERR;
    }

    @Override
    public ReaderExt.READER_ERR writeTagEPC(byte[] data, byte[] accesspwd, short timeout) {
        try {
            byte[] errorcode = new byte[1];
            int result = mReader.WriteEPC_G2(
                    (byte) (data.length / 2),
                    data,
                    accesspwd,
                    errorcode
            );
            return result == 0 ? ReaderExt.READER_ERR.MT_OK_ERR : ReaderExt.READER_ERR.MT_OTHER_ERR;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ReaderExt.READER_ERR.MT_OTHER_ERR;
    }

    @Override
    public ReaderExt.READER_ERR writeTagEPCByFilter(byte[] data, byte[] accesspwd,
                                                    short timeout, byte[] fdata, int fbank, int fstartaddr, boolean matching) {
        try {
            setInventoryFilter(fdata, fbank, fstartaddr, matching);
            return writeTagEPC(data, accesspwd, timeout);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            setCancleInventoryFilter();
        }
        return ReaderExt.READER_ERR.MT_OTHER_ERR;
    }

    @Override
    public ReaderExt.READER_ERR lockTag(ReaderExt.Lock_Obj lockobject,
                                        ReaderExt.Lock_Type locktype, byte[] accesspasswd, int timeout) {
        try {
            byte[] errorcode = new byte[1];
            // 转换锁定对象和类型到荣锐SDK的格式
            byte select = 0x01;
            switch (lockobject) {
                case LOCK_OBJECT_KILL_PASSWORD:
                    select = 0x00;
                    break;
                case LOCK_OBJECT_ACCESS_PASSWD:
                    select = 0x01;
                    break;
                case LOCK_OBJ_EPC_MEMORY:
                    select = 0x02;
                    break;
                case LOCK_OBJECT_TID_MEMORY:
                    select = 0x03;
                    break;
                case LOCK_OBJECT_USER_MEMORY:
                    select = 0x04;
                    break;
            }

            byte setprotect = 0x02;
            switch (locktype) {
                case ACCESS_PASSWD_UNLOCK:
                    setprotect = 0x00;
                    break;
                case ACCESS_PASSWD_PERM_UNLOCK:
                    setprotect = 0x01;
                    break;
                case ACCESS_PASSWD_LOCK:
                    setprotect = 0x02;
                    break;
                case ACCESS_PASSWD_PERM_LOCK:
                    setprotect = 0x03;
                    break;
            }

            int result = mReader.Lock_G2(
                    (byte) 0, // 广播方式
                    new byte[0], // EPC为空
                    select,
                    setprotect,
                    accesspasswd,
                    errorcode
            );
            return result == 0 ? ReaderExt.READER_ERR.MT_OK_ERR : ReaderExt.READER_ERR.MT_OTHER_ERR;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ReaderExt.READER_ERR.MT_OTHER_ERR;
    }

    @Override
    public ReaderExt.READER_ERR lockTagByFilter(ReaderExt.Lock_Obj lockobject,
                                                ReaderExt.Lock_Type locktype, byte[] accesspasswd, short timeout,
                                                byte[] fdata, int fbank, int fstartaddr, boolean matching) {
        setInventoryFilter(fdata, fbank, fstartaddr, matching);
        return lockTag(lockobject, locktype, accesspasswd, timeout);
    }

    @Override
    public ReaderExt.READER_ERR killTag(byte[] killpasswd, int timeout) {
        try {
            byte[] errorcode = new byte[1];
            int result = mReader.Kill_G2(
                    (byte) 0, // 广播方式
                    new byte[0], // EPC为空
                    killpasswd,
                    errorcode
            );
            return result == 0 ? ReaderExt.READER_ERR.MT_OK_ERR : ReaderExt.READER_ERR.MT_OTHER_ERR;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ReaderExt.READER_ERR.MT_OTHER_ERR;
    }

    @Override
    public ReaderExt.READER_ERR killTagByFilter(byte[] killpasswd, int timeout,
                                                byte[] fdata, int fbank, int fstartaddr, boolean matching) {
        setInventoryFilter(fdata, fbank, fstartaddr, matching);
        return killTag(killpasswd, timeout);
    }

    @Override
    public ReaderExt.READER_ERR setPower(int power) {
        try {
            // 检查功率范围
            if (power < 0 || power > 33) {
                return ReaderExt.READER_ERR.MT_OTHER_ERR;
            }
            int code = mReader.SetRfPower((byte) power);
            return code == 0 ? ReaderExt.READER_ERR.MT_OK_ERR : ReaderExt.READER_ERR.MT_OTHER_ERR;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ReaderExt.READER_ERR.MT_OTHER_ERR;
    }

    @Override
    public int[] getPower() {
        byte[] Version = new byte[2];
        byte[] Power = new byte[1];
        byte[] band = new byte[1];
        byte[] MaxFre = new byte[1];
        byte[] MinFre = new byte[1];
        mReader.GetReaderInformation(Version, Power, band, MaxFre, MinFre);
        return new int[]{Power[0]};
    }

    @Override
    public void setSingleLabelMode(boolean enabled) {
        try {
            ReaderParameter param = mReader.GetInventoryPatameter();
            // 设置QValue为0可以实现单标签模式
            param.QValue = enabled ? (byte) 0 : (byte) 4;
            mReader.SetInventoryPatameter(param);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void setGroupTidMode(boolean enabled) {
        try {
            ReaderParameter param = mReader.GetInventoryPatameter();
            // 设置混合查询模式
            param.IvtType = enabled ? (byte) 2 : (byte) 0;
            param.Memory = (byte) 1;
            param.Interval = 0;
            mReader.ModuleType = 2;
            mReader.SetInventoryPatameter(param);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public ReaderExt.READER_ERR setFastMode() {
        return ReaderExt.READER_ERR.MT_OK_ERR;
    }

    @Override
    public boolean setInventoryParameter(Map<String, Object> params) {
        return true;
    }

    @Override
    public String getInventoryParameter() {
        return "";
    }

    @Override
    public int getTemperature() {
        try {
            String temperature = mReader.GetRFIDTempreture();
            return temperature != null ? Integer.parseInt(temperature) : -1;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    @Override
    public boolean close() {
        clearTagList();
        int code = mReader.DisConnect();
        LogU.d("RongRuiUHFManager close:"+code);
        isConnect = false;
        return code == 0;
    }

    @Override
    public String getSession() {
        try {
            ReaderParameter param = mReader.GetInventoryPatameter();
            switch (param.Session) {
                case 0:
                    return "S0";
                case 1:
                    return "S1";
                case 2:
                    return "S2";
                case 3:
                    return "S3";
                default:
                    return "";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public String getFlag() {
        return "";
    }
    @Override
    public ReaderExt.READER_ERR setRegion(int region) {
        int[] frequencyPoints = null;

        switch (region) {
            case 0: // RG_PRC
                frequencyPoints = new int[20];
                for (int i = 0; i < 20; i++) {
                    frequencyPoints[i] = 840125 + i * 250;
                }
                break;
            case 1: // RG_PRC2
                frequencyPoints = new int[20];
                for (int i = 0; i < 20; i++) {
                    frequencyPoints[i] = 920125 + i * 250;
                }
                break;
            case 2: // RG_NONE
                frequencyPoints = new int[0]; // 无频点
                break;
            case 3: // RG_NA
                frequencyPoints = new int[50];
                for (int i = 0; i < 50; i++) {
                    frequencyPoints[i] = 902750 + i * 500;
                }
                break;
            case 4: // RG_EU3
                frequencyPoints = new int[15];
                for (int i = 0; i < 15; i++) {
                    frequencyPoints[i] = 865100 + i * 200;
                }
                break;
            default:
                return ReaderExt.READER_ERR.MT_OTHER_ERR; // 非法区域，返回错误
        }

        return setFrequencyPoints(frequencyPoints);
    }
    @Override
    public ReaderExt.Region_Conf getRegion() {
        try {
            byte[] version = new byte[2];
            byte[] power = new byte[1];
            byte[] band = new byte[1];
            byte[] maxFre = new byte[1];
            byte[] minFre = new byte[1];

            int result = mReader.GetReaderInformation(version, power, band, maxFre, minFre);
            if (result == 0) {
                switch (band[0]) {
                    case 8:
                        return ReaderExt.Region_Conf.RG_PRC;
                    case 1:
                        return ReaderExt.Region_Conf.RG_PRC2;
                    case 2:
                        return ReaderExt.Region_Conf.RG_NA;
                    case 4:
                        return ReaderExt.Region_Conf.RG_EU3;
                    default:
                        return ReaderExt.Region_Conf.RG_NONE;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ReaderExt.Region_Conf.RG_NONE;
    }
    @Override
    public int[] getFrequencyPoints() {
        try {
            byte[] version = new byte[2];
            byte[] power = new byte[1];
            byte[] band = new byte[1];
            byte[] maxFre = new byte[1];
            byte[] minFre = new byte[1];

            int result = mReader.GetReaderInformation(version, power, band, maxFre, minFre);
            if (result == 0) {
                // 根据频段计算频点
                switch (band[0] & 0xFF) {
                    case 1: { // Chinese band2
                        int[] points = new int[20];
                        for (int i = 0; i < 20; i++) {
                            points[i] = 920125 + i * 250;
                        }
                        return points;
                    }
                    case 2: { // US band
                        int[] points = new int[50];
                        for (int i = 0; i < 50; i++) {
                            points[i] = 902750 + i * 500;
                        }
                        return points;
                    }
                    case 3: { // Korean band
                        int[] points = new int[32];
                        for (int i = 0; i < 32; i++) {
                            points[i] = 917100 + i * 200;
                        }
                        return points;
                    }
                    case 4: { // EU band
                        int[] points = new int[15];
                        for (int i = 0; i < 15; i++) {
                            points[i] = 865100 + i * 200;
                        }
                        return points;
                    }
                    case 8: { // Chinese band1
                        int[] points = new int[20];
                        for (int i = 0; i < 20; i++) {
                            points[i] = 840125 + i * 250;
                        }
                        return points;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public ReaderExt.READER_ERR setFrequencyPoints(int[] frequencyPoints) {
        try {
            if (frequencyPoints == null || frequencyPoints.length == 0) {
                return ReaderExt.READER_ERR.MT_OTHER_ERR;
            }

            // 根据第一个频点判断频段
            int freq = frequencyPoints[0];
            byte band;
            byte maxfre;
            byte minfre;

            if (freq >= 920125 && freq <= 924875) { // Chinese band2
                band = 1;
                maxfre = 19;
                minfre = 0;
            } else if (freq >= 902750 && freq <= 927250) { // US band
                band = 2;
                maxfre = 49;
                minfre = 0;
            } else if (freq >= 917100 && freq <= 923300) { // Korean band
                band = 3;
                maxfre = 31;
                minfre = 0;
            } else if (freq >= 865100 && freq <= 867900) { // EU band
                band = 4;
                maxfre = 14;
                minfre = 0;
            } else if (freq >= 840125 && freq <= 844875) { // Chinese band1
                band = 8;
                maxfre = 19;
                minfre = 0;
            } else {
                return ReaderExt.READER_ERR.MT_OTHER_ERR;
            }

            int result = mReader.SetRegion(band, maxfre, minfre);
            return result == 0 ? ReaderExt.READER_ERR.MT_OK_ERR : ReaderExt.READER_ERR.MT_OTHER_ERR;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ReaderExt.READER_ERR.MT_OTHER_ERR;
    }

    @Override
    public int getProtocol() {
        try {
            byte[] profile = new byte[1];
            int result = mReader.GetProfile(profile);
            if (result == 0) {
                switch (profile[0] & 0xFF) {
                    case 11: return 0;  // Profile11: 640kHZ, FM0
                    case 1:  return 1;  // Profile1: 640kHZ, Miller2
                    case 15: return 2;  // Profile15: 640kHZ, Miller4
                    case 12: return 3;  // Profile12: 320kHZ, Miller2
                    case 3:  return 4;  // Profile3: 320kHZ, Miller2
                    case 5:  return 5;  // Profile5: 320kHZ, Miller4
                    case 7:  return 6;  // Profile7: 250kHZ, Miller4
                    case 13: return 7;  // Profile13: 160kHZ, Miller8
                    case 50: return 8;  // Profile50: 640kHZ, FM0
                    default: return -1;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    @Override
    public ReaderExt.READER_ERR setProtocol(String protocol) {
        try {
            // 将协议字符串转换为Profile值
            byte profile;
            switch (protocol.toUpperCase()) {
                case "FM0":
                    profile = 11;     // Profile11: 640kHZ, FM0
                    break;
                case "MILLER2":
                    profile = 1;      // Profile1: 640kHZ, Miller2
                    break;
                case "MILLER4":
                    profile = 15;     // Profile15: 640kHZ, Miller4
                    break;
                case "MILLER8":
                    profile = 13;     // Profile13: 160kHZ, Miller8
                    break;
                default:
                    return ReaderExt.READER_ERR.MT_OTHER_ERR;
            }

            int result = mReader.SetProfile(profile);
            return result == 0 ? ReaderExt.READER_ERR.MT_OK_ERR : ReaderExt.READER_ERR.MT_OTHER_ERR;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ReaderExt.READER_ERR.MT_OTHER_ERR;
    }

    @Override
    public int getQValue() {
        try {
            ReaderParameter param = mReader.GetInventoryPatameter();
            return param.QValue;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    @Override
    public ReaderExt.READER_ERR setQValue(int selectedPosition) {
        try {
            if (selectedPosition < 0 || selectedPosition > 15) {
                return ReaderExt.READER_ERR.MT_OTHER_ERR;
            }

            ReaderParameter param = mReader.GetInventoryPatameter();
            param.QValue = (byte) selectedPosition;
            mReader.SetInventoryPatameter(param);
            return ReaderExt.READER_ERR.MT_OK_ERR;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ReaderExt.READER_ERR.MT_OTHER_ERR;
    }
}
